﻿using System;
using System.Collections.Generic;
using System.Text;
using IBatisNet.Common.Utilities.Objects;
using System.Reflection;
using IBatisNet.Common.Utilities.Objects.Members;

namespace Ecreate.Data.IFace
{
    public class SecureGetAccessorFactory : IGetAccessorFactory
    {
        public IGetAccessor CreateGetAccessor(Type targetType, string name)
        {
            return new SecureGetAccessor(targetType, name);
        }
    }

    public class SecureSetAccessorFactory : ISetAccessorFactory
    {
        public ISetAccessor CreateSetAccessor(Type targetType, string name)
        {
            return new SecureSetAccessor(targetType, name);
        }
    }
    public class SecureGetAccessor : IGetAccessor
    {
        private PropertyInfo _propertyInfo = null;
        private string _propertyName = string.Empty;
        private Type _targetType = null;
        private bool _isProtected = false;

        public SecureGetAccessor(Type targetType, string propertyName)
        {
            ReflectionInfo reflectionCache = ReflectionInfo.GetInstance( targetType );
            _propertyInfo = (PropertyInfo)reflectionCache.GetGetter(propertyName);

            object[] attrs = _propertyInfo.GetCustomAttributes(typeof(ProtectFieldAttribute), true);
            _isProtected = attrs.Length > 0;

            _targetType = targetType;
            _propertyName = propertyName;
         }

        #region IAccessor Members

        public string Name
        {
            get { return _propertyInfo.Name; }
        }

        public Type MemberType
        {
            get { return _propertyInfo.PropertyType; }
        }

        #endregion

        #region IGet Members

        public object Get(object target)
        {
            if (_propertyInfo.CanRead)
            {
                object ret = _propertyInfo.GetValue(target, null);
                if (_isProtected)
                {
                    // 加密
                    ret = null;// SecureUtil.EncryptData(ret);
                }
                return ret;
            }
            else
            {
                throw new NotSupportedException(
                    string.Format("Property \"{0}\" on type "
                    + "{1} doesn't have a get method.", _propertyName, _targetType));
            }
        }

        #endregion
    }

    public class SecureSetAccessor : ISetAccessor
    {
        private PropertyInfo _propertyInfo = null;
        private string _propertyName = string.Empty;
        private Type _targetType = null;
        private bool _isProtected = false;

        public SecureSetAccessor(Type targetType, string propertyName)
        {
            ReflectionInfo reflectionCache = ReflectionInfo.GetInstance(targetType);
            _propertyInfo = (PropertyInfo)reflectionCache.GetGetter(propertyName);

            object[] attrs = _propertyInfo.GetCustomAttributes(typeof(ProtectFieldAttribute), true);
            _isProtected = attrs.Length > 0;

            _targetType = targetType;
            _propertyName = propertyName;
        }


        #region IAccessor Members

        public string Name
        {
            get { return _propertyInfo.Name; }
        }

        public Type MemberType
        {
            get { return _propertyInfo.PropertyType; }
        }

        #endregion

        #region IGet Members

        public void Set(object target, object value)
        {
            if (_propertyInfo.CanWrite)
            {
                if (_isProtected)
                {
                    // 解密
                    //value = SecureUtil.DecryptData(value);
                }

                _propertyInfo.SetValue(target, value, null);
            }
            else
            {
                throw new NotSupportedException(
                    string.Format("Property \"{0}\" on type "
                    + "{1} doesn't have a set method.", _propertyName, _targetType));
            }
        }

        #endregion

    }




}
